/* eslint-disable vue/no-parsing-error */
<template>
  <div
    id="primaryDiv"
    style="height: calc(100vh - 16px); width: calc(100vw - 16px)"
  ></div>

  <xml id="toolbox" style="display: none">
    <category id="catLogic" colour="#4C97FF" name="逻辑">
      <block type="controls_if"></block>
      <block type="logic_compare"></block>
      <block type="logic_operation"></block>
      <block type="logic_negate"></block>
      <block type="logic_boolean"></block>
      <block type="logic_null"></block>
      <block type="logic_ternary"></block>
    </category>
    <category id="catLoops" colour="#0FBD8C" name="循环">
      <block type="controls_repeat_ext">
        <value name="TIMES">
          <shadow type="math_number">
            <field name="NUM">10</field>
          </shadow>
        </value>
      </block>
      <block type="controls_whileUntil"></block>
      <block type="controls_for">
        <value name="FROM">
          <shadow type="math_number">
            <field name="NUM">1</field>
          </shadow>
        </value>
        <value name="TO">
          <shadow type="math_number">
            <field name="NUM">10</field>
          </shadow>
        </value>
        <value name="BY">
          <shadow type="math_number">
            <field name="NUM">1</field>
          </shadow>
        </value>
      </block>
      <block type="controls_forEach"></block>
      <block type="controls_flow_statements"></block>
    </category>
    <category id="catMath" colour="#59C059" name="数学">
      <block type="math_number"></block>
      <block type="math_arithmetic">
        <value name="A">
          <shadow type="math_number">
            <field name="NUM">1</field>
          </shadow>
        </value>
        <value name="B">
          <shadow type="math_number">
            <field name="NUM">1</field>
          </shadow>
        </value>
      </block>
      <block type="math_single">
        <value name="NUM">
          <shadow type="math_number">
            <field name="NUM">9</field>
          </shadow>
        </value>
      </block>
      <block type="math_trig">
        <value name="NUM">
          <shadow type="math_number">
            <field name="NUM">45</field>
          </shadow>
        </value>
      </block>
      <block type="math_constant"></block>
      <block type="math_number_property">
        <value name="NUMBER_TO_CHECK">
          <shadow type="math_number">
            <field name="NUM">0</field>
          </shadow>
        </value>
      </block>
      <block type="math_change">
        <value name="DELTA">
          <shadow type="math_number">
            <field name="NUM">1</field>
          </shadow>
        </value>
      </block>
      <block type="math_round">
        <value name="NUM">
          <shadow type="math_number">
            <field name="NUM">3.1</field>
          </shadow>
        </value>
      </block>
      <block type="math_on_list"></block>
      <block type="math_modulo">
        <value name="DIVIDEND">
          <shadow type="math_number">
            <field name="NUM">64</field>
          </shadow>
        </value>
        <value name="DIVISOR">
          <shadow type="math_number">
            <field name="NUM">10</field>
          </shadow>
        </value>
      </block>
      <block type="math_constrain">
        <value name="VALUE">
          <shadow type="math_number">
            <field name="NUM">50</field>
          </shadow>
        </value>
        <value name="LOW">
          <shadow type="math_number">
            <field name="NUM">1</field>
          </shadow>
        </value>
        <value name="HIGH">
          <shadow type="math_number">
            <field name="NUM">100</field>
          </shadow>
        </value>
      </block>
      <block type="math_random_int">
        <value name="FROM">
          <shadow type="math_number">
            <field name="NUM">1</field>
          </shadow>
        </value>
        <value name="TO">
          <shadow type="math_number">
            <field name="NUM">100</field>
          </shadow>
        </value>
      </block>
      <block type="math_random_float"></block>
    </category>
    <category id="catText" colour="#FFBF00" name="文本">
      <block type="text"></block>
      <block type="text_join"></block>
      <block type="text_append">
        <value name="TEXT">
          <shadow type="text"></shadow>
        </value>
      </block>
      <block type="text_length">
        <value name="VALUE">
          <shadow type="text">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
      </block>
      <block type="text_isEmpty">
        <value name="VALUE">
          <shadow type="text">
            <field name="TEXT"></field>
          </shadow>
        </value>
      </block>
      <block type="text_indexOf">
        <value name="VALUE">
          <block type="variables_get">
            <field name="VAR">text</field>
          </block>
        </value>
        <value name="FIND">
          <shadow type="text">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
      </block>
      <block type="text_charAt">
        <value name="VALUE">
          <block type="variables_get">
            <field name="VAR">text</field>
          </block>
        </value>
      </block>
      <block type="text_getSubstring">
        <value name="STRING">
          <block type="variables_get">
            <field name="VAR">text</field>
          </block>
        </value>
      </block>
      <block type="text_changeCase">
        <value name="TEXT">
          <shadow type="text">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
      </block>
      <block type="text_trim">
        <value name="TEXT">
          <shadow type="text">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
      </block>
      <block type="text_print">
        <value name="TEXT">
          <shadow type="text">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
      </block>
      <block type="text_prompt_ext">
        <value name="TEXT">
          <shadow type="text">
            <field name="TEXT">abc</field>
          </shadow>
        </value>
      </block>
    </category>
    <category id="catLists" colour="#9966FF" name="列表">
      <block type="lists_create_with">
        <mutation items="0"></mutation>
      </block>
      <block type="lists_create_with"></block>
      <block type="lists_repeat">
        <value name="NUM">
          <shadow type="math_number">
            <field name="NUM">5</field>
          </shadow>
        </value>
      </block>
      <block type="lists_length"></block>
      <block type="lists_isEmpty"></block>
      <block type="lists_indexOf">
        <value name="VALUE">
          <block type="variables_get">
            <field name="VAR">list</field>
          </block>
        </value>
      </block>
      <block type="lists_getIndex">
        <value name="VALUE">
          <block type="variables_get">
            <field name="VAR">list</field>
          </block>
        </value>
      </block>
      <block type="lists_setIndex">
        <value name="LIST">
          <block type="variables_get">
            <field name="VAR">list</field>
          </block>
        </value>
      </block>
      <block type="lists_getSublist">
        <value name="LIST">
          <block type="variables_get">
            <field name="VAR">list</field>
          </block>
        </value>
      </block>
      <block type="lists_split">
        <value name="DELIM">
          <shadow type="text">
            <field name="TEXT">,</field>
          </shadow>
        </value>
      </block>
      <block type="lists_sort"></block>
    </category>
    <category id="catColour" colour="#CF63CF" name="颜色">
      <block type="colour_picker"></block>
      <block type="colour_random"></block>
      <block type="colour_rgb">
        <value name="RED">
          <shadow type="math_number">
            <field name="NUM">100</field>
          </shadow>
        </value>
        <value name="GREEN">
          <shadow type="math_number">
            <field name="NUM">50</field>
          </shadow>
        </value>
        <value name="BLUE">
          <shadow type="math_number">
            <field name="NUM">0</field>
          </shadow>
        </value>
      </block>
      <block type="colour_blend">
        <value name="COLOUR1">
          <shadow type="colour_picker">
            <field name="COLOUR">#ff0000</field>
          </shadow>
        </value>
        <value name="COLOUR2">
          <shadow type="colour_picker">
            <field name="COLOUR">#3333ff</field>
          </shadow>
        </value>
        <value name="RATIO">
          <shadow type="math_number">
            <field name="NUM">0.5</field>
          </shadow>
        </value>
      </block>
    </category>
    <sep></sep>
    <category
      id="catVariables"
      colour="#FF8C1A"
      custom="VARIABLE"
      name="变量"
    ></category>
    <category
      id="catFunctions"
      colour="#FF6680"
      custom="PROCEDURE"
      name="函数"
    ></category>
  </xml>

  <xml id="blocklyDefault" style="display: none">
    <block type="variables_set">
      <field name="VAR">Count</field>
      <value name="VALUE">
        <block type="math_number">
          <field name="NUM">1</field>
        </block>
      </value>
      <next>
        <block type="controls_whileUntil" x="16" y="16">
          <field name="MODE">WHILE</field>
          <value name="BOOL">
            <block type="logic_compare">
              <field name="OP">LTE</field>
              <value name="A">
                <block type="variables_get">
                  <field name="VAR">Count</field>
                </block>
              </value>
              <value name="B">
                <block type="math_number">
                  <field name="NUM">3</field>
                </block>
              </value>
            </block>
          </value>
          <statement name="DO">
            <block type="text_print">
              <value name="TEXT">
                <block type="text">
                  <field name="TEXT">Hello World!</field>
                </block>
              </value>
              <next>
                <block type="variables_set">
                  <field name="VAR">Count</field>
                  <value name="VALUE">
                    <block type="math_arithmetic">
                      <field name="OP">ADD</field>
                      <value name="A">
                        <block type="variables_get">
                          <field name="VAR">Count</field>
                        </block>
                      </value>
                      <value name="B">
                        <block type="math_number">
                          <field name="NUM">1</field>
                        </block>
                      </value>
                    </block>
                  </value>
                </block>
              </next>
            </block>
          </statement>
        </block>
      </next>
    </block>
  </xml>

  <xml id="blocklyEmpty" style="display: none"> </xml>
  <!--<img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>-->
</template>

<script>
import Blockly from "./utils/blockly";
import Interpreter from "js-interpreter";
import axios from "axios";
import * as ZH_HANS from "./utils/blockly/msg/zh-hans";
import "./utils/blockly/python";
import "./utils/blockly/javascript";
import "./utils/blockly/php";
import "./utils/blockly/dart";
import "./utils/blockly/lua";
Blockly.setLocale(ZH_HANS);

var workspace;

function customAlert(text, callback) {
  const div = document.createElement("div");
  div.style =
    "position:fixed;top:32px;left:10vw;width:80vw;background-color:#f0f0f0;border-radius:10px;padding:0 16px 16px;box-sizing:border-box;z-index:9999;box-shadow:0 0 4px rgb(0 0 0 / 14%), 0 4px 8px rgb(0 0 0 / 28%);";
  div.id = "ohos-value-prompt";
  div.innerHTML = `<p>${text}</p><div style="float:right"><button id="ohos-value-confirm" style="display: inline-flex;justify-content: center;align-items: center;line-height: 1;height: 32px;white-space: nowrap;cursor: pointer;-webkit-appearance: none;text-align: center;box-sizing: border-box;outline: none;font-weight: 500;user-select: none;vertical-align: middle;padding: 8px 15px;font-size: 14px;border-radius: 4px;background-color:#409eff;border:1px solid #409eff;color:#fff;margin-right:12px;"><span>确定</span></button></div>`;
  document.querySelector("body").appendChild(div);
  document
    .getElementById("ohos-value-confirm")
    .addEventListener("click", function () {
      document.getElementById("ohos-value-prompt").remove();
      callback(undefined);
    });
}

function customPrompt(text, callback) {
  const div = document.createElement("div");
  div.style =
    "position:fixed;top:32px;left:10vw;width:80vw;background-color:#f0f0f0;border-radius:10px;padding:0 16px 16px;box-sizing:border-box;z-index:9999;box-shadow:0 0 4px rgb(0 0 0 / 14%), 0 4px 8px rgb(0 0 0 / 28%);";
  div.id = "ohos-value-prompt";
  div.innerHTML = `<p>${text}</p><input id="ohos-value-input" style="width: 100%;-webkit-appearance: none;color: #606266;background-color:#ffffff;font-size: inherit;height: 32px;line-height: 32px;padding: 0 11px;outline: none;border:none;border-raduis: 4px;box-shadow:0 0 0 1px #dcdfe6 inset;box-sizing: border-box;margin-bottom:12px;" /><div style="float:right"><button id="ohos-value-confirm" style="display: inline-flex;justify-content: center;align-items: center;line-height: 1;height: 32px;white-space: nowrap;cursor: pointer;-webkit-appearance: none;text-align: center;box-sizing: border-box;outline: none;font-weight: 500;user-select: none;vertical-align: middle;padding: 8px 15px;font-size: 14px;border-radius: 4px;background-color:#409eff;border:1px solid #409eff;color:#fff;margin-right:12px;"><span>确定</span></button><button id="ohos-value-cancel" style="display: inline-flex;justify-content: center;align-items: center;line-height: 1;height: 32px;white-space: nowrap;cursor: pointer;-webkit-appearance: none;text-align: center;box-sizing: border-box;outline: none;font-weight: 500;user-select: none;vertical-align: middle;padding: 8px 15px;font-size: 14px;border-radius: 4px;background-color:#909399;border:1px solid #909399;color:#fff">取消</button></div>`;
  document.querySelector("body").appendChild(div);
  document
    .getElementById("ohos-value-confirm")
    .addEventListener("click", function () {
      const value = document.getElementById("ohos-value-input").value;
      document.getElementById("ohos-value-prompt").remove();
      callback(value);
    });
  document
    .getElementById("ohos-value-cancel")
    .addEventListener("click", function () {
      const value = document.getElementById("ohos-value-input").value;
      document.getElementById("ohos-value-prompt").remove();
      callback(value);
    });
}

export default {
  name: "App",
  mounted() {
    var params = {
      mode: "0",
    };
    var searchParams = location.search.substring(1).split("&");
    if (searchParams) {
      for (let i = 0, l = searchParams.length; i < l; i++) {
        let param = searchParams[i].split("=");
        params[param[0]] = param[1];
      }
    }
    workspace = Blockly.inject("primaryDiv", {
      toolbox: document.getElementById("toolbox"),
    });
    workspace.setTheme(Blockly.Themes.Zelos);
    const xml = localStorage.getItem("content-save");
    switch (params.mode) {
      case "0":
        if (xml) {
          Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
        } else {
          const defaultBlocks = document.getElementById("blocklyDefault");
          Blockly.Xml.domToWorkspace(defaultBlocks, workspace);
        }
        workspace.addChangeListener(this.updateFunction);
        break;
      case "1":
        workspace.addChangeListener(this.checkFunction);
        break;
    }
    this.mode = params.mode;
    window.resetWorkspace = this.resetWorkspace;
    window.getCode = this.getCode;
    window.inspectCode = this.inspectCode;
    window.runCode = this.runCode;
    window.setTargetCode = this.setTargetCode;
  },
  methods: {
    updateFunction() {
      const text = Blockly.Xml.domToText(Blockly.Xml.workspaceToDom(workspace));
      localStorage.setItem("content-save", text);
      const code = Blockly.JavaScript.workspaceToCode(workspace);
      localStorage.setItem("code-save", code);
    },
    checkFunction() {
      const code = Blockly.JavaScript.workspaceToCode(workspace);
      if (code == localStorage.getItem("target-code")) {
        if (document.title != this.code) {
          document.title = this.code;
        }
        console.log("success");
      }
    },
    resetWorkspace() {
      const defaultBlocks = document.getElementById("blocklyDefault");
      const emptyBlocks = document.getElementById("blocklyEmpty");
      switch (this.mode) {
        case "0":
          if (
            Blockly.Xml.clearWorkspaceAndLoadFromXml(defaultBlocks, workspace)
          ) {
            return "success";
          } else {
            return "fail";
          }
        case "1":
        case "2":
          if (
            Blockly.Xml.clearWorkspaceAndLoadFromXml(emptyBlocks, workspace)
          ) {
            return "success";
          } else {
            return "fail";
          }
      }
    },
    getCode(language) {
      return Blockly[language || "JavaScript"].workspaceToCode(workspace);
    },
    inspectCode() {
      const code = Blockly.JavaScript.workspaceToCode(workspace);
      if (code == localStorage.getItem("target-code")) {
        console.log("right");
        return true;
      }
      else {
        console.log("wrong");
        return false;
      }
    },
    setTargetCode(code) {
      this.code = code;
      if (code != "Run") {
        axios
          .get(`https://lyrbbding.site/files/codingblockly/checkpoints/${code}`)
          .then((res) => {
            let code = res.data;
            code = code.replace(/\r\n/g, "\n");
            localStorage.setItem("target-code", code);
          });
      }
      return "success";
    },
    runCode() {
      var code = Blockly.JavaScript.workspaceToCode(workspace);
      let that = this;
      var initFunc = function (interpreter, scope) {
        var alertWrapper = function (text, callback) {
          text = text ? text.toString() : "";
          return customAlert(text, callback);
        };
        interpreter.setProperty(
          scope,
          "alert",
          interpreter.createAsyncFunction(alertWrapper)
        );
        var promptWrapper = function (text, callback) {
          text = text ? text.toString() : "";
          return customPrompt(text, callback);
        };
        interpreter.setProperty(
          scope,
          "prompt",
          interpreter.createAsyncFunction(promptWrapper)
        );
        var numberWrapper = function (text) {
          text = text ? Number(text) : 0;
          return text;
        };
        interpreter.setProperty(
          scope,
          "Number",
          interpreter.createNativeFunction(numberWrapper)
        );
      };
      var myInterpreter = new Interpreter(code, initFunc);
      // eslint-disable-next-line no-unused-vars
      const codeRunner = function () {
        if (myInterpreter) {
          var hasMore = myInterpreter.run();
          if (hasMore) {
            setTimeout(codeRunner, 10);
          } else {
            console.log(that.code);
            if (that.code == "Run") {
              if (document.title != that.code) {
                document.title = that.code;
              }
            }
            console.log("finish");
          }
        }
      };
      codeRunner();
    },
  },
};
</script>

<style>
html {
  height: 100%;
  margin: 0;
  padding: 0;
}
body {
  height: calc(100% - 16px);
  margin: 8px;
  padding: 0;
}
</style>
